﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MadProps.Definition
{
    static class MetadataStore
    {
        static Dictionary<PropId, Dictionary<string, object>> values
            = new Dictionary<PropId, Dictionary<string, object>>();

        internal static void SetValue(PropId propId, string key, object value)
        {
            if (!values.ContainsKey(propId))
            {
                throw new Exception("This should never happen");
            }
            values[propId][key] = value;
        }

        internal static object GetValue(PropId propId, string key, object defaultValue = null)
        {
            if (!values.ContainsKey(propId))
            {
                throw new Exception("Metadata has not been built yet!"); // TODO better exception
            }
            var dict = values[propId];

            if (!dict.ContainsKey(key))
            {
                return defaultValue;
            }
            return dict[key];
        }

        internal static T GetValue<T>(PropId propId, Meta.Key<T> key)
        {
            object result = GetValue(propId, key.theString);
            if (result == null)
            {
                return default(T);
            }
            return (T)result;
        }

        static bool IsBuilt(PropId prop)
        {
            return values.ContainsKey(prop);
        }

        internal static void Build(PropId prop, Composition composition)
        {
            lock (values)
            {
                if (IsBuilt(prop))
                {
                    return;
                }

                var dict = new Dictionary<string, object>();
                var args = new MetadataBuildArgs(prop, dict);
                foreach (var builder in composition.ResolveAll<IMetadataBuilder>())
                {
                    builder.OnBuilding(args);
                }

                values[prop] = dict;
            }
        }
    }
}
